/*
* Copyright 2010 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.ning.metrics.goodwill.endpoint;
import com.google.inject.Inject;
import com.ning.metrics.goodwill.access.GoodwillSchema;
import com.ning.metrics.goodwill.binder.config.GoodwillConfig;
import com.ning.metrics.goodwill.modules.ThriftRegistrar;
import com.ning.metrics.goodwill.sink.GoodwillSink;
import com.ning.metrics.goodwill.store.GoodwillStore;
import com.sun.jersey.api.view.Viewable;
import org.apache.log4j.Logger;
import javax.annotation.Nullable;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
@Path("registrar")
public class Registrar
{
private Logger log = Logger.getLogger(Registrar.class);
private GoodwillStore store;
private final GoodwillSink sink;
private final GoodwillConfig config;
@Inject
public Registrar(
GoodwillConfig config,
GoodwillStore store,
@Nullable GoodwillSink sink
)
{
this.config = config;
this.store = store;
this.sink = sink;
if (sink != null) {
this.store.setSink(sink);
}
}
/*
* UI
*/
@GET
@Produces(MediaType.TEXT_HTML)
public Viewable getAll() throws IOException
{
ThriftRegistrar registrar = new ThriftRegistrar(store.toJSON());
registrar.setActionCoreURL(config.getActionCoreURL());
return new Viewable("/registrar/type.jsp", registrar);
}
/*
* REST API
*/
@GET
@Produces("application/json")
public Response getAllJson() throws IOException
{
return Response.ok(store.toJSON().toString()).type(MediaType.APPLICATION_JSON_TYPE).build();
}
@GET
@Produces("application/json")
@Path("/{type}/")
public Response getTypeJson(@PathParam("type") String typeName) throws IOException
{
if (typeName == null) {
return Response.ok(store.toJSON().toString()).type(MediaType.APPLICATION_JSON_TYPE).build();
}
else {
GoodwillSchema typeFound = store.findByName(typeName);
if (typeFound != null) {
return Response.ok(typeFound.toJSON().toString()).type(MediaType.APPLICATION_JSON_TYPE).build();
}
}
return Response.status(Response.Status.NOT_FOUND).build();
}
@DELETE
@Path("/{type}/")
public Response deleteType(@PathParam("type") String typeName) throws IOException
{
if (!config.allowDeleteEvent()) {
return Response.status(Response.Status.FORBIDDEN).build();
}
if (typeName == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
else {
GoodwillSchema typeFound = store.findByName(typeName);
if (typeFound != null) {
if (store.deleteType(typeFound)) {
return Response.noContent().build();
}
else {
return Response.status(Response.Status.SERVICE_UNAVAILABLE).build();
}
}
else {
// Don't! The condition is not necessarily permanent!
//return Response.status(Response.Status.GONE)
return Response.status(Response.Status.NOT_FOUND).build();
}
}
}
@POST
@Consumes("application/json")
public Response post(String jsonThriftTypeString)
{
try {
GoodwillSchema schema = GoodwillSchema.decode(jsonThriftTypeString);
// Use PUT to update a Schema
if (store.findByName(schema.getName()) != null) {
return Response.status(Response.Status.CONFLICT).build();
}
store.addType(schema);
log.info(String.format("Created new ThriftType <%s> from JSON <%s>", schema.toString(), jsonThriftTypeString));
}
catch (IOException e) {
log.warn(String.format("Malformatted JSON: %s (%s)", jsonThriftTypeString, e));
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.status(Response.Status.CREATED).build();
}
@PUT
@Consumes("application/json")
public Response put(String jsonThriftTypeString)
{
try {
GoodwillSchema thriftType = GoodwillSchema.decode(jsonThriftTypeString);
store.updateType(thriftType);
log.info(String.format("Updated ThriftType <%s> from JSON <%s>", thriftType.toString(), jsonThriftTypeString));
}
catch (IOException e) {
log.warn(String.format("Malformatted JSON: %s", jsonThriftTypeString));
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.status(Response.Status.ACCEPTED).build();
}
}